package com.wxm.killing.mq.consumer;

import com.wxm.killing.mq.common.datasource.IPKeyGenerator;
import com.wxm.killing.mq.common.util.CommonUtil;
import com.wxm.killing.mq.common.util.DateUtil;
import com.wxm.killing.mq.common.util.JsonUtil;
import com.wxm.killing.mq.dao.*;
import com.wxm.killing.mq.entity.*;
import com.wxm.killing.mq.service.CommonCacheService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * @Description 消息消费者
 * @author: wxm
 * @date: 2019/10/10 22:59
 * @version: 1.0
 */
@Component
public class JMSConsumer {
    private final static Logger logger = LoggerFactory.getLogger(JMSConsumer.class);

    @Autowired
    private IPKeyGenerator iPKeyGenerator;

    @Autowired
    private TbContractRushStatusDao tbContractRushStatusDao;

    @Autowired
    private TbSysConfigDao tbSysConfigDao;

    @Autowired
    private TbUserDao tbUserDao;

    @Autowired
    private TbUserBankDao tbUserBankDao;

    @Autowired
    private TbContractDao tbContractDao;

    @Autowired
    private TbContractBuyDao tbContractBuyDao;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private TbContractRushBuyDao tbContractRushBuyDao;

    @Autowired
    private TbContractRushOrderDao tbContractRushOrderDao;

    @Autowired
    private TbContractRushSellDao tbContractRushSellDao;

    @Autowired
    private TbLogUserUpgradeDao tbLogUserUpgradeDao;

    @Autowired
    private CommonCacheService commonCacheService;


    @JmsListener(destination = "rushBuy.queue")
    @Transactional
    public void receiveQueue(String msg) {
        logger.info("JMSConsumer.receiveQueue start:" + msg);
        Long startTime = System.currentTimeMillis();
        //开始抢购
        RushBuyMsg rushBuyMsg = JsonUtil.Json2Java(msg, RushBuyMsg.class);
        TbContractRushStatus tbContractRushStatus = new TbContractRushStatus();
        tbContractRushStatus.setContractRushBuyStatusId(rushBuyMsg.getContractRushBuyStatusId());
        tbContractRushStatus.setStatus(2);
        // 判断系统配置
        //获取所有的系统配置
        List<TbSysConfig> tbSysConfigList = commonCacheService.getConfigAll();
        Map<String, String> codeValueMap = new HashMap<>();
        if (CollectionUtils.isEmpty(tbSysConfigList)) {
            tbContractRushStatus.setMsg("系统配置异常");
            tbContractRushStatus.setContent("系统配置异常");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("系统配置异常");
            return;
        }
        //系统配置存放到map  code=value格式
        for (TbSysConfig tbSysConfig : tbSysConfigList) {
            codeValueMap.put(tbSysConfig.getCode(), tbSysConfig.getValue());
        }
        String contractRushIsOpen = codeValueMap.get("contract_rush_is_open");
        if (StringUtils.isEmpty(contractRushIsOpen) || "0".equals(contractRushIsOpen)) {
            tbContractRushStatus.setMsg("系统已关闭抢购");
            tbContractRushStatus.setContent("contractRushIsOpen为空或=0");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("contractRushIsOpen为空或=0");
            return;
        }

        String apply_start_time = codeValueMap.get("contract_rush_start_time");
        String apply_end_time = codeValueMap.get("contract_rush_end_time");
        if (!DateUtil.isEffectiveDate(apply_start_time, apply_end_time)) {
            tbContractRushStatus.setMsg("抢购开启时间：" + apply_start_time + "~" + apply_end_time);
            tbContractRushStatus.setContent("抢购开启时间-系统");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("抢购开启时间-系统");
            return;
        }
        //判断会员信息
        //获取用户信息
        Integer userId = rushBuyMsg.getUserId();
        TbUser tbUser = commonCacheService.getUserById(userId);
        if (tbUser.getIsOpenRush() != 1) {
            tbContractRushStatus.setMsg("当前账户未开启抢购");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("当前账户未开启抢购");
            return;
        }
        //判断用户是否绑定银行卡
        TbUserBank tbUserBankParam = new TbUserBank();
        tbUserBankParam.setUserId(userId);
        List<TbUserBank> tbUserBankList = tbUserBankDao.select(tbUserBankParam);
        if (CollectionUtils.isEmpty(tbUserBankList)) {
            tbContractRushStatus.setMsg("请先完善银行卡信息");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("请先完善银行卡信息");
            return;
        }
        Integer contractId = rushBuyMsg.getContractId();
        TbContract tbContract = commonCacheService.getBycontractId(contractId);
        if (tbContract == null) {
            tbContractRushStatus.setMsg("抢购失败，商铺不存在");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("抢购失败，商铺不存在");
            return;
        }
        //合约时间判断
        if(!DateUtil.isEffectiveDate(tbContract.getRushStartTime(),tbContract.getRushEndTime())){
            tbContractRushStatus.setMsg("抢购开启时间：" + tbContract.getRushStartTime() + "~" + tbContract.getRushEndTime());
            tbContractRushStatus.setContent("抢购开启时间-合约");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("抢购开启时间-合约");
            return;
        }
        //需要购买合约
        if (1 == tbContract.getContractIsOpen()) {
            //判断用户是否购买合约
            TbContractBuy tbContractBuyParam = new TbContractBuy();
            tbContractBuyParam.setContractId(contractId);
            tbContractBuyParam.setUserId(userId);
            tbContractBuyParam.setStatus(1);
            TbContractBuy tbContractBuy = tbContractBuyDao.selectOne(tbContractBuyParam);
            if (tbContractBuy == null) {
                tbContractRushStatus.setMsg("抢购失败，请先购买合约");
                tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
                logger.info("购失败，请先购买合约");
                return;
            }
            String sql = " SELECT price from tb_data_coin_price ORDER BY id desc LIMIT 0,1 ";
            //获取单价
            BigDecimal coinPrice = jdbcTemplate.queryForObject(sql, BigDecimal.class);
            //判断用户合约数量是否充足
            if (coinPrice.multiply(tbContractBuy.getNumberBalance()).compareTo(tbContract.getContractMinPrice()) < 1) {
                tbContractRushStatus.setMsg("抢购失败，合约数量不足，无法为您抢购订单");
                tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
                logger.info("抢购失败，合约数量不足，无法为您抢购订单");
                return;
            }
        }
        //判断是否已抢购-单个商店
        List<Integer> sqlBuyTodayParam = new ArrayList<Integer>();
        sqlBuyTodayParam.add(userId);
        sqlBuyTodayParam.add(contractId);
        String sqlCountBuyToday = " select count(*) from tb_contract_rush_buy where to_days(create_time) = to_days(now())AND type=2 AND status IN(0,1,2,3) AND user_id = ? AND contract_id = ? ";
        int countBuyToday = jdbcTemplate.queryForObject(sqlCountBuyToday, sqlBuyTodayParam.toArray(), Integer.class);
        if (countBuyToday > 0) {
            tbContractRushStatus.setMsg("已有抢购订单");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("已有抢购订单");
            return;
        }
        //系统配置最大抢购数量--全部商店
        if (!codeValueMap.containsKey("contract_rush_max_order")) {
            tbContractRushStatus.setMsg("contract_rush_max_order系统配置异常");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("contract_rush_max_order系统配置异常");
            return;
        }
        String maxOrder = codeValueMap.get("contract_rush_max_order");
        //统计当天抢购订单
        String sqlCountBuyOrderToday = " select count(*) from tb_contract_rush_buy where  type=2 AND status IN(0,1,2,3) AND to_days(create_time) = to_days(now()) ";
        int countBuyOrderToday = jdbcTemplate.queryForObject(sqlCountBuyOrderToday, Integer.class);
        if (countBuyOrderToday > Integer.valueOf(maxOrder)) {
            tbContractRushStatus.setMsg("超过每日开放数量");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("超过每日开放数量");
            return;
        }

        //每日最大抢购金额-全部商店
        if (!codeValueMap.containsKey("contract_rush_max_money")) {
            tbContractRushStatus.setMsg("contract_rush_max_money系统配置异常");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("contract_rush_max_money系统配置异常");
            return;
        }
        //系统配置最大抢购金额
        String maxMoneyStr = codeValueMap.get("contract_rush_max_money");
        //统计当天抢购数量
        String sqlCountBuyMoneyToday = " select sum(number) from tb_contract_rush_order where type=2 AND status IN(0,1,2,3) AND to_days(create_time) = to_days(now()) ";
        BigDecimal countBuyMoneyToday = jdbcTemplate.queryForObject(sqlCountBuyMoneyToday, BigDecimal.class);
        if (countBuyMoneyToday != null) {
            BigDecimal maxMoney = new BigDecimal(maxMoneyStr);
            if (maxMoney.compareTo(countBuyMoneyToday) == -1) {
                tbContractRushStatus.setMsg("匹配完毕，请明天加油");
                tbContractRushStatus.setContent("统计当天抢购数量:系统:"+maxMoneyStr+"，当前："+countBuyMoneyToday);
                tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
                logger.info("统计当天抢购数量:系统:"+maxMoneyStr+"，当前："+countBuyMoneyToday);
                return;
            }
        }


        //查看已有卖单
        String sqlSell = "SELECT s.*,u.referee_family_ids FROM tb_contract_rush_sell as s,tb_user as u WHERE u.is_lock=0 and s.user_id = u.user_id AND s.status=1  AND s.contract_id =" + contractId + " ORDER BY s.complaint_form_order_id DESC,s.parent_id DESC";
        //String sqlSell = "SELECT s.*,u.referee_family_ids FROM tb_contract_rush_sell as s,tb_user as u WHERE u.is_lock=0 and s.user_id = u.user_id AND s.status=1  AND s.contract_id =" + contractId + " order by rand() ";
        List<Map<String, Object>> sellList = jdbcTemplate.queryForList(sqlSell);
        if (CollectionUtils.isEmpty(sellList)) {
            tbContractRushStatus.setMsg("匹配完毕，请明天加油");
            tbContractRushStatus.setContent("卖单不足");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("卖单不足");
            return;
        }
        String refereeFamilyIds = tbUser.getRefereeFamilyIds();
        Map<String, Object> mapSelect = new HashMap<>();
        for (Map<String, Object> map : sellList) {
            if (map.get("user_id").toString().equals(userId.toString())) {
                // 不能匹配自己
                continue;
            }
            if (map.get("referee_family_ids").toString().indexOf(refereeFamilyIds + userId + ",") != -1) {
                // 我的下级不匹配，他的家族有我
                continue;
            }
            if (refereeFamilyIds.indexOf(map.get("referee_family_ids").toString() + map.get("user_id") + ",") != -1) {
                // 上级不匹配，我的家族有他
                continue;
            }
            //随机睡0-0.5S
            try{
                Thread.sleep(Long.valueOf(String.valueOf(new Random().nextInt(500))));
            }catch (Exception e){
                logger.error("随机睡"+e.toString());
            }
            //避免多线程更新同一条记录触发事物
            //获取订单详情
            TbContractRushSell tbContractRushSellDetail = tbContractRushSellDao.selectByPrimaryKey(CommonUtil.getInteger(map, "sell_id"));
            if(tbContractRushSellDetail.getStatus() == 2){
                continue;
            }
            //乐观锁
            //更新卖单状态
            int countUpdate = tbContractRushSellDao.updateContractRushSellByIdAndStatus(CommonUtil.getInteger(map, "sell_id"), CommonUtil.getInteger(map, "status"));
            if (1 != countUpdate) {
                continue;
            }
            mapSelect = map;
            break;
        }
        if (CollectionUtils.isEmpty(mapSelect)) {
            tbContractRushStatus.setMsg("匹配完毕，请明天加油");
            tbContractRushStatus.setContent("没有可以匹配的卖单");
            tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
            logger.info("没有可以匹配的卖单");
            return;
        }
        //创建
        Date createTime = new Date();
        // 生成抢购记录
        TbContractRushBuy tbContractRushBuy = new TbContractRushBuy();
        tbContractRushBuy.setUserId(userId);
        tbContractRushBuy.setType(2);
        tbContractRushBuy.setContractId(contractId);
        tbContractRushBuy.setNumber((BigDecimal) mapSelect.get("number"));
        tbContractRushBuy.setPayAddress(JsonUtil.Java2Json(tbUserBankList));
        tbContractRushBuy.setStatus(2);
        tbContractRushBuy.setLeaseProfitNumber(new BigDecimal(0));
        tbContractRushBuy.setCreateTime(createTime);
        tbContractRushBuy.setLeaseDay(tbContract.getCycleDay());
        tbContractRushBuy.setLeaseProfitRate(tbContract.getRushRateTotal());
        tbContractRushBuy.setLeaseBurningRate(tbContract.getRushBurnTotalRate());
        tbContractRushBuyDao.insertSelectiveRId(tbContractRushBuy);
        //生成sn
        String buySn = CommonUtil.createContractRushBuySn(tbContractRushBuy.getBuyId());
        TbContractRushBuy tbContractRushBuyUpdateSn = new TbContractRushBuy();
        tbContractRushBuyUpdateSn.setBuyId(tbContractRushBuy.getBuyId());
        tbContractRushBuyUpdateSn.setSn(buySn);
        tbContractRushBuyDao.updateByPrimaryKeySelective(tbContractRushBuyUpdateSn);

        // 生成抢购单
        TbContractRushOrder tbContractRushOrder = new TbContractRushOrder();
        tbContractRushOrder.setType(2);
        tbContractRushOrder.setContractId(contractId);
        tbContractRushOrder.setNumber((BigDecimal) mapSelect.get("number"));
        tbContractRushOrder.setStatus(0);
        tbContractRushOrder.setBuyId(tbContractRushBuy.getBuyId());
        tbContractRushOrder.setBuySn(buySn);
        tbContractRushOrder.setBuyUserId(tbContractRushBuy.getUserId().toString());
        tbContractRushOrder.setBuyPayAddress(tbContractRushBuy.getPayAddress());
        tbContractRushOrder.setLeaseDay(tbContractRushBuy.getLeaseDay());
        tbContractRushOrder.setLeaseProfitRate(tbContractRushBuy.getLeaseProfitRate());
        tbContractRushOrder.setLeaseProfitNumber(tbContractRushBuy.getLeaseProfitNumber());
        tbContractRushOrder.setLeaseBurningRate(tbContractRushBuy.getLeaseBurningRate());
        tbContractRushOrder.setSellUserId(CommonUtil.getString(mapSelect, "user_id"));
        tbContractRushOrder.setSellSn(CommonUtil.getString(mapSelect, "sn"));
        tbContractRushOrder.setSellId(CommonUtil.getInteger(mapSelect, "sell_id"));
        tbContractRushOrder.setSellPayAddress(CommonUtil.getString(mapSelect, "pay_address"));
        tbContractRushOrder.setCreateTime(createTime);
        tbContractRushOrderDao.insertSelectiveRId(tbContractRushOrder);
        //生成sn
        String orderSn = CommonUtil.createContractRushOrderSn(tbContractRushOrder.getBuyId());
        TbContractRushOrder tbContractRushOrderUpdateSn = new TbContractRushOrder();
        tbContractRushOrderUpdateSn.setOrderId(tbContractRushOrder.getOrderId());
        tbContractRushOrderUpdateSn.setOrderSn(orderSn);
        tbContractRushOrderDao.updateByPrimaryKeySelective(tbContractRushOrderUpdateSn);

        //更新抢购状态表
        tbContractRushStatus.setMsg("抢购成功");
        tbContractRushStatus.setStatus(1);
        tbContractRushStatus.setOrderId(tbContractRushOrder.getOrderId());
        tbContractRushStatusDao.updateByPrimaryKeySelective(tbContractRushStatus);
//        //更新用户为活跃
//        if (1 == tbUser.getIsActiveUser()) {
//            return;
//        }
//        TbUser tbUserUpdate = new TbUser();
//        tbUserUpdate.setUserId(tbUser.getUserId());
//        tbUserUpdate.setIsActiveUser(1);
//        tbUserDao.updateByPrimaryKeySelective(tbUserUpdate);
//        //更新上级的等级
//        if (StringUtils.isEmpty(refereeFamilyIds)) {
//            return;
//        }
//        //1获取所有的上级 字段referee_family_ids存放了所有的上级ID
//        List<TbUser> tbUserParentList = tbUserDao.selectByIds(refereeFamilyIds.substring(0, refereeFamilyIds.length() - 1));
//        if (CollectionUtils.isEmpty(tbUserParentList)) {
//            return;
//        }
//        //获取等级配置
//        String userLevelSqlAll = "SELECT * from tb_user_level where is_enable=1 ORDER BY level_id DESC";
//        List<TbUserLevel> userLevelList = jdbcTemplate.query(userLevelSqlAll, new RowMapper<TbUserLevel>() {
//            @Override
//            public TbUserLevel mapRow(ResultSet rs, int rowNum) throws SQLException {
//                TbUserLevel tbUserLevel = new TbUserLevel();
//                tbUserLevel.setConditionDirectPushNumber(rs.getInt("condition_direct_push_number"));
//                tbUserLevel.setConditionTeamNumber(rs.getInt("condition_team_number"));
//                tbUserLevel.setConditionUpperLevelCount(rs.getInt("condition_upper_level_count"));
//                tbUserLevel.setLevelId(rs.getInt("level_id"));
//                return tbUserLevel;
//            }
//        });
//        Date dateUpgrageTime = new Date();
//        for (TbUser tbUserParentTemp : tbUserParentList) {
//            //=0就不去升级降级
//            if (0 == tbUserParentTemp.getIsUpgradeLevel()) {
//                continue;
//            }
//            //直推人数 --自己的下级
//            TbUser tbUserDirectParam = new TbUser();
//            tbUserDirectParam.setRefereeId(tbUserParentTemp.getUserId());
//            tbUserDirectParam.setIsActiveUser(1);
//            int directMemberNumber = tbUserDao.selectCount(tbUserDirectParam);
//            String tbUserParentTempRefereeFamilyIds = tbUserParentTemp.getRefereeFamilyIds();
//            if (StringUtils.isEmpty(tbUserParentTempRefereeFamilyIds)) {
//                tbUserParentTempRefereeFamilyIds = "";
//            }
//            String note = "抢购";
//            //团队人数--自己的下级，下下级。。。。
//            String teamSql = "SELECT count(*) from tb_user where referee_family_ids like '" + tbUserParentTempRefereeFamilyIds + tbUserParentTemp.getUserId() + ",%" + "' AND is_active_user=1";
//            int teamMemberNumber = jdbcTemplate.queryForObject(teamSql, Integer.class);
//            note = note + "直推人数：" + directMemberNumber + "团队人数：" + teamMemberNumber;
//            TbUserLevel tbUserLevelHit = null;
//            for (TbUserLevel tbUserLevel : userLevelList) {
//                int levelId = tbUserLevel.getLevelId() - 1;
//                //下级人数
//                String levelSql = "SELECT count(*) from tb_user where referee_id=" + tbUserParentTemp.getUserId() + " AND level_id>=" + levelId + " and is_active_user=1";
//                int levelMemberNumber = jdbcTemplate.queryForObject(levelSql, Integer.class);
//                if (directMemberNumber >= tbUserLevel.getConditionDirectPushNumber()
//                        && teamMemberNumber >= tbUserLevel.getConditionTeamNumber()
//                        && levelMemberNumber >= tbUserLevel.getConditionUpperLevelCount()) {
//                    tbUserLevelHit = tbUserLevel;
//                    note = note + "下一级别人数：" + levelMemberNumber;
//                    break;
//                }
//            }
//            if (tbUserLevelHit != null) {
//                if (!tbUserLevelHit.getLevelId().equals(tbUserParentTemp.getLevelId())) {
//                    //更新用户等级
//                    TbUser tbUserUpdateLevelParam = new TbUser();
//                    tbUserUpdateLevelParam.setUserId(tbUserParentTemp.getUserId());
//                    tbUserUpdateLevelParam.setLevelId(tbUserLevelHit.getLevelId());
//                    tbUserUpdateLevelParam.setLevelAwardId(tbUserLevelHit.getLevelId());
//                    tbUserDao.updateByPrimaryKeySelective(tbUserUpdateLevelParam);
//                    //记录日志
//                    TbLogUserUpgrade tbLogUserUpgradeInsertParam = new TbLogUserUpgrade();
//                    tbLogUserUpgradeInsertParam.setUserId(tbUserParentTemp.getUserId());
//                    tbLogUserUpgradeInsertParam.setCurrentLevelId(tbUserParentTemp.getLevelId());
//                    tbLogUserUpgradeInsertParam.setUpgradeLevelId(tbUserLevelHit.getLevelId());
//                    tbLogUserUpgradeInsertParam.setCreateTime(dateUpgrageTime);
//                    tbLogUserUpgradeInsertParam.setContent(note);
//                    tbLogUserUpgradeDao.insertSelective(tbLogUserUpgradeInsertParam);
//                }
//            }
//
//        }
        Long endTime = System.currentTimeMillis();
        Long useTime = endTime - startTime;
        logger.info("JMSConsumer.receiveQueue end耗时："+useTime);
    }

    public static void main(String[] args) {
        for(int i=0 ;i<10000;i++){
            try{
                logger.error("随机睡");
                Thread.sleep(Long.valueOf(String.valueOf(new Random().nextInt(400))));
            }catch (Exception e){
                logger.error("随机睡"+e.toString());
            }
        }

    }

}